#pragma once
#include "../common/dispatcher.hpp"
#include "../client/rpc_client.hpp"
#include "rpc_router.hpp"
#include "rpc_registry.hpp"
#include "rpc_topic.hpp"

namespace myrpc {
    namespace server {
        // 服务注册服务端
        class RegisterServer {
        public:
            using ptr = std::shared_ptr<RegisterServer>;
            RegisterServer(const Address &addr)
            :_pd_manager(std::make_shared<PDManager>()),
            _dispatcher(std::make_shared<Dispatcher>()),
            _addr(addr)
            {
                server_logger->INFO("初始化服务注册中心: %s:%d", addr.first.c_str(), addr.second);
                auto svr_req_cb=std::bind(&PDManager::onServiceRequest, _pd_manager.get(), std::placeholders::_1, std::placeholders::_2);
                _dispatcher->registerHandler<ServiceRequest>(MsgType::REQ_SERVICE, svr_req_cb);
                _server = ServerFactory::create<MuduoServer>(addr.second);
                // 设置服务注册服务端的消息处理回调
                auto msg_cb = std::bind(&Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallBack(msg_cb);
                // 设置服务注册服务端的连接关闭回调处理
                auto close_cb = std::bind(&RegisterServer::onConnShutdown, this, std::placeholders::_1);
                _server->setCloseCallBack(close_cb);
            }
            void start(){
                server_logger->INFO("服务注册中心启动: %s:%d", _addr.first.c_str(), _addr.second);
                server_logger->INFO("等待服务提供者注册和客户端发现请求...");
                _server->start();
            }

        private:
            void onConnShutdown(const BaseConnection::ptr &conn){
                _pd_manager->onConnshutdown(conn);
            }

        private:
            Address _addr;
            PDManager::ptr _pd_manager;
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server;
        }; 

        // Rpc服务调用服务端
        class RpcServer {
        public:
            using ptr = std::shared_ptr<RpcServer>;
            RpcServer(const Address &access_addr, bool enableRegistry = false, const Address &registry_server_addr = Address())
            :_enableRegistry(enableRegistry),
            _access_addr(access_addr),
            _registry_server_addr(registry_server_addr),
            _router(std::make_shared<RpcRouter>()),
            _dispatcher(std::make_shared<Dispatcher>())
            {
                server_logger->INFO("初始化RPC服务端: %s:%d", access_addr.first.c_str(), access_addr.second);
                if (_enableRegistry){
                    server_logger->INFO("启用服务注册功能: %s:%d", 
                        registry_server_addr.first.c_str(), registry_server_addr.second);
                    _registry_client = std::make_shared<client::RegistryClient>(
                        registry_server_addr.first, registry_server_addr.second);
                }
                else{
                    server_logger->INFO("独立模式运行 (未启用服务注册)");
                }
                auto rpc_req_cb=std::bind(&RpcRouter::onRpcRequest, _router.get(), std::placeholders::_1, std::placeholders::_2);
                _dispatcher->registerHandler<RpcRequest>(MsgType::REQ_RPC, rpc_req_cb);
                auto msg_cb = std::bind(&Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server = ServerFactory::create<MuduoServer>(access_addr.second);
                _server->setMessageCallBack(msg_cb);
            }

            void start(){
                server_logger->INFO("RPC服务端启动: %s:%d", _access_addr.first.c_str(), _access_addr.second);
                if (_enableRegistry){
                    server_logger->INFO("连接到注册中心: %s:%d", 
                        _registry_server_addr.first.c_str(), _registry_server_addr.second);
                }
                server_logger->INFO("等待客户端RPC调用请求...");
                _server->start();
            }

            void registryMethod(const ServiceDescribe::ptr &service){
                // 向服务注册中心注册服务
                if (_enableRegistry){
                    server_logger->INFO("向注册中心注册服务: '%s'", service->getMethod().c_str());
                    _registry_client->registerMethod(service->getMethod(), _access_addr);
                }
                // 向Rpc服务管理者中注册服务
                _router->registerService(service);
            }

        private:
            Address _access_addr;
            Address _registry_server_addr;
            bool _enableRegistry;
            client::RegistryClient::ptr _registry_client;
            RpcRouter::ptr _router;
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server;
        };

        // 发布订阅服务端
        class TopicServer
        {
        public:
            using ptr = std::shared_ptr<TopicServer>;
            TopicServer(const Address &addr)
                : _topic_manager(std::make_shared<TopicManager>()),
                  _dispatcher(std::make_shared<Dispatcher>()),
                  _addr(addr)
            {
                server_logger->INFO("初始化发布订阅中心: %s:%d", addr.first.c_str(), addr.second);
                auto top_req_cb = std::bind(&TopicManager::onTopicRequest, _topic_manager.get(), std::placeholders::_1, std::placeholders::_2);
                _dispatcher->registerHandler<TopicRequest>(MsgType::REQ_TOPIC, top_req_cb);
                _server = ServerFactory::create<MuduoServer>(addr.second);
                // 设置发布订阅服务端的消息处理回调
                auto msg_cb = std::bind(&Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallBack(msg_cb);
                // 设置发布订阅服务端的连接关闭回调处理
                auto close_cb = std::bind(&TopicServer::onConnShutdown, this, std::placeholders::_1);
                _server->setCloseCallBack(close_cb);
            }
            void start(){
                server_logger->INFO("发布订阅中心启动: %s:%d", _addr.first.c_str(), _addr.second);
                _server->start();
            }

        private:
            void onConnShutdown(const BaseConnection::ptr &conn){
                _topic_manager->onConnshutdown(conn);
            }

        private:
            Address _addr;
            TopicManager::ptr _topic_manager;
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server;
        };
    }
}